#include "common.h"

#define GET_CONFIG(name,buf) \
	if(get_config(name,buf,MAXNAME) < 0) { \
		MSG("get_config failed:%s",name); \
		exit(EXIT_FAILURE); \
	} \
	//printf("(%s)\n",buf);

static pid_t pid_scan;
static pid_t pid_getNames;
static pid_t pid_buildIndex;
//static pid_t pid_webPage;

static int get_config(char *name,char *buf,int size);
static void sig_int(int signo);

int main(void) {

	char config_sites[MAXNAME];
	char config_sites_submitted[MAXNAME];
	char config_bugs_reported[MAXNAME];
	char config_scan_from[MAXNAME];
	char config_scan_to[MAXNAME];
	char config_scan_num_thread[MAXNAME];
	char config_getNames_num_process[MAXNAME];
	char config_dataNames[MAXNAME];
	char config_dataIndex[MAXNAME];
	char config_dataIndex_cache[MAXNAME];
	char config_listening_port[MAXNAME];
	char config_scan_interval_minutes[MAXNAME];
	unsigned long scan_interval;

	GET_CONFIG(CONFIG_SITES,config_sites);
	GET_CONFIG(CONFIG_SITES_SUBMITTED,config_sites_submitted);
	GET_CONFIG(CONFIG_BUGS_REPORTED,config_bugs_reported);
	GET_CONFIG(CONFIG_SCAN_FROM,config_scan_from);
	GET_CONFIG(CONFIG_SCAN_TO,config_scan_to);
	GET_CONFIG(CONFIG_SCAN_NUM_THREAD,config_scan_num_thread);
	GET_CONFIG(CONFIG_GETNAMES_NUM_PROCESS,config_getNames_num_process);
	GET_CONFIG(CONFIG_DATANAMES,config_dataNames);
	GET_CONFIG(CONFIG_DATAINDEX,config_dataIndex);
	//GET_CONFIG(CONFIG_LISTENING_PORT,config_listening_port);
	GET_CONFIG(CONFIG_SCAN_INTERVAL_MINUTES,config_scan_interval_minutes);

	snprintf(config_dataIndex_cache,MAXNAME,"%s%s",config_dataIndex,CACHE_SUFFIX);

	scan_interval = strtol(config_scan_interval_minutes,NULL,10);
	scan_interval *= 60;
	
	if(signal(SIGINT,sig_int) == SIG_ERR) {
		MSG("signal failed:SIGINT");
		exit(EXIT_FAILURE);
	}

	if(signal(SIGTERM,sig_int) == SIG_ERR) {
		MSG("signal failed:SIGTERM");
		exit(EXIT_FAILURE);
	}

	/*
	pid_webPage = fork();
	if(pid_webPage < 0) {
		MSG("fork failed:webPage");
		exit(EXIT_FAILURE);
	}
	else if(pid_webPage == 0) {
		execl("./webPage","./webPage",config_listening_port,
						config_dataIndex,
						config_sites_submitted,
						config_bugs_reported,NULL);
		exit(EXIT_SUCCESS);
	}
	run_log("webPage started");
	*/

	int fd_log = open("log/main.log",O_WRONLY|O_CREAT|O_TRUNC,0644);
	if(fd_log < 0) {
		MSG("open failed:log/main.log");
	}
	close(STDOUT_FILENO);
	dup(fd_log);

	while(1) {
		pid_scan = fork();
		if(pid_scan < 0) {
			pid_scan = 0;
			MSG("fork failed:pid_scan");
			if(kill(getpid(),SIGINT) < 0) {
				MSG("kill failed");
				exit(EXIT_FAILURE);
			}
			pause();
		}
		else if(pid_scan == 0) {
			int fd_log;

			fd_log = open("log/scan.log",O_WRONLY|O_CREAT|O_TRUNC,0644);
			close(STDOUT_FILENO);
			dup(fd_log);
			execl("./scan","./scan",config_sites_submitted,config_sites,
						config_scan_from,config_scan_to,
						config_scan_num_thread,NULL);
			exit(EXIT_SUCCESS);
		}
		else {
			run_log("main - scan started");
		}
		
		if(waitpid(pid_scan,NULL,0) < 0) {
			MSG("waitpid failed:pid_scan");
		}
		pid_scan = 0;
		run_log("main - scan finished");
		
		///////////////
		pid_getNames = fork();
		if(pid_getNames < 0) {
			pid_getNames = 0;
			MSG("fork failed:pid_getNames");
			if(kill(getpid(),SIGINT) < 0) {
				MSG("kill failed");
				exit(EXIT_FAILURE);
			}
			pause();
		}
		else if(pid_getNames == 0) {
			int fd_log;

			fd_log = open("log/getNames.log",O_WRONLY|O_CREAT|O_TRUNC,0644);
			close(STDOUT_FILENO);
			dup(fd_log);
			execl("./getNames","./getNames",config_sites,config_dataNames,
							config_getNames_num_process,NULL);

			exit(EXIT_SUCCESS);
		}
		else {
			run_log("main - getNames started");
		}
		if(waitpid(pid_getNames,NULL,0) < 0) {
			MSG("waitpid failed:pid_getNames");
		}
		pid_getNames = 0;
		run_log("main - getNames finished");
		////////////////
		
		pid_buildIndex = fork();
		if(pid_buildIndex < 0) {
			pid_buildIndex = 0;
			MSG("fork failed:pid_buildIndex");
			if(kill(getpid(),SIGINT) < 0) {
				MSG("kill failed");
				exit(EXIT_FAILURE);
			}
			pause();
		}
		else if(pid_buildIndex == 0) {
			int fd_log;

			fd_log = open("log/buildIndex.log",O_WRONLY|O_CREAT|O_TRUNC,0644);
			close(STDOUT_FILENO);
			dup(fd_log);
			execl("./buildIndex","./buildIndex",config_dataNames,
								config_dataIndex_cache,
								config_dataIndex,NULL);
			exit(EXIT_SUCCESS);
		}
		else {
			run_log("main - buildIndex started");
		}
		
		if(waitpid(pid_buildIndex,NULL,0) < 0) {
			MSG("waitpid failed:pid_buildIndex");
		}
		pid_buildIndex = 0;
		run_log("main - buildIndex finished");

		////////////////
		run_log("done,sleep for %lu seconds",scan_interval);
		fflush(stdout);
		sleep(scan_interval);
		//sleep(5);
	}


	exit(EXIT_SUCCESS);
}

static int get_config(char *name,char *buf,int size) {
	char config[MAXNAME];
	char *tmp;

	FILE *fp = fopen(FILE_CONFIG,"r");
	if(fp == NULL) {
		MSG("fopen failed:%s",FILE_CONFIG);
		return -1;
	}

	while(fgets(config,MAXNAME,fp) != NULL) {
		if(strncmp(config,name,strlen(name)) == 0) {
			config[strlen(config)-1] = 0;

			tmp = strchr(config,'=');
			if(tmp == NULL) {
				MSG("wrong config line:%s",config);
				fclose(fp);
				return -1;
			}
			strncpy(buf,(tmp+1),size);
			fclose(fp);
			return 0;
		}
	}

	fclose(fp);
	return -1;
}

static void sig_int(int signo) {
	/*
	if(pid_webPage != 0) {
		kill(pid_webPage,SIGINT);
		if(waitpid(pid_webPage,NULL,0) < 0) {
			MSG("wait for pid_webPage failed");
		}
	}
	*/
	if(pid_scan != 0) {
		kill(pid_scan,SIGINT);
		if(waitpid(pid_scan,NULL,0) < 0) {
			MSG("wait for pid_scan failed");
		}
	}
	if(pid_getNames != 0) {
		kill(pid_getNames,SIGINT);
		if(waitpid(pid_getNames,NULL,0) < 0) {
			MSG("wait for pid_getNames failed");
		}
	}
	if(pid_buildIndex != 0) {
		kill(pid_buildIndex,SIGINT);
		if(waitpid(pid_buildIndex,NULL,0) < 0) {
			MSG("wait for pid_buildIndex failed");
		}
	}

	exit(EXIT_SUCCESS);
}
